<template>
  <view class="tui-swipeout-wrap">
    <view
      class="tui-swipeout-item"
      :class="[isShowBtn ? 'swipe-action-show' : '']"
      @touchstart="handlerTouchstart"
      @touchmove="handlerTouchmove"
      @touchend="handlerTouchend"
      :style="{ transform: 'translate(' + position.pageX + 'px,0)' }"
    >
      <view class="tui-swipeout-content">
        <slot name="content"></slot>
      </view>
      <view
        class="tui-swipeout-button-right-group"
        v-if="actions.length > 0"
        @touchend.stop="loop"
      >
        <view
          class="tui-swipeout-button-right-item"
          v-for="(item, index) in actions"
          :key="index"
          :style="{
            background: item.background || '#f7f7f7',
            color: item.color,
            width: item.width + 'px'
          }"
          :data-index="index"
          @tap="handlerButton"
        >
          <image
            :src="item.icon"
            v-if="item.icon"
            :style="{ width: px(item.imgWidth), height: px(item.imgHeight) }"
          ></image>
          <text :style="{ fontSize: px(item.fontsize) }">{{ item.name }}</text>
        </view>
      </view>
      <!--actions长度设置为0，可直接传按钮进来-->
      <view
        class="tui-swipeout-button-right-group"
        @touchend.stop="loop"
        @tap="handlerParentButton"
        v-if="actions.length === 0"
        :style="{
          width: operateWidth + 'px',
          right: '-' + operateWidth + 'px'
        }"
      >
        <slot name="button"></slot>
      </view>
    </view>
    <view
      v-if="isShowBtn && showMask"
      class="swipe-action_mask"
      @tap="closeButtonGroup"
      @touchmove.stop="closeButtonGroup"
    />
  </view>
</template>

<script>
export default {
  name: "tuiSwipeAction",
  props: {
    // name: '删除',
    // color: '#fff',
    // fontsize: 32,//单位upx
    // width: 80, //单位px
    // icon: 'like.png',//此处为图片地址
    // background: '#ed3f14'
    actions: {
      type: Array,
      default: function() {
        return [];
      }
    },
    //是否可关闭，默认可关闭，可以单独控制
    closable: {
      type: Boolean,
      default: true
    },
    //设为false，可以滑动多行不关闭菜单
    showMask: {
      type: Boolean,
      default: true
    },
    operateWidth: {
      type: Number,
      default: 80
    },
    params: {
      type: Object,
      default: function() {
        return {};
      }
    }
  },
  watch: {
    actions(newValue, oldValue) {
      this.updateButtonSize();
    }
  },
  data() {
    return {
      //start position
      tStart: {
        pageX: 0,
        pageY: 0
      },
      //限制滑动距离
      limitMove: 0,
      //move position
      position: {
        pageX: 0,
        pageY: 0
      },
      isShowBtn: false
    };
  },
  // #ifdef H5
  mounted() {
    this.updateButtonSize();
  },
  // #endif
  onReady() {
    this.updateButtonSize();
  },
  methods: {
    swipeDirection(x1, x2, y1, y2) {
      return Math.abs(x1 - x2) >= Math.abs(y1 - y2)
        ? x1 - x2 > 0
          ? "Left"
          : "Right"
        : y1 - y2 > 0
        ? "Up"
        : "Down";
    },
    //阻止事件冒泡
    loop() {},
    updateButtonSize() {
      const actions = this.actions;
      if (actions.length > 0) {
        const query = uni.createSelectorQuery().in(this);
        let limitMovePosition = 0;
        actions.forEach(item => {
          limitMovePosition += item.width || 0;
        });
        this.limitMove = limitMovePosition;
      } else {
        this.limitMove = this.operateWidth;
      }
    },
    handlerTouchstart(event) {
      const touches = event.touches ? event.touches[0] : {};
      const tStart = this.tStart;
      if (touches) {
        for (let i in tStart) {
          if (touches[i]) {
            tStart[i] = touches[i];
          }
        }
      }
    },
    swipper(touches) {
      const start = this.tStart;
      const spacing = {
        pageX: touches.pageX - start.pageX,
        pageY: touches.pageY - start.pageY
      };
      if (this.limitMove < Math.abs(spacing.pageX)) {
        spacing.pageX = -this.limitMove;
      }
      this.position = spacing;
    },
    handlerTouchmove(event) {
      const start = this.tStart;
      const touches = event.touches ? event.touches[0] : {};
      if (touches) {
        const direction = this.swipeDirection(
          start.pageX,
          touches.pageX,
          start.pageY,
          touches.pageY
        );
        if (direction === "Left") {
          this.swipper(touches);
        }
      }
    },
    handlerTouchend(event) {
      const start = this.tStart;
      const touches = event.changedTouches ? event.changedTouches[0] : {};
      if (touches) {
        const direction = this.swipeDirection(
          start.pageX,
          touches.pageX,
          start.pageY,
          touches.pageY
        );
        const spacing = {
          pageX: touches.pageX - start.pageX,
          pageY: touches.pageY - start.pageY
        };
        if (Math.abs(spacing.pageX) >= 40 && direction === "Left") {
          spacing.pageX = spacing.pageX < 0 ? -this.limitMove : this.limitMove;
          this.isShowBtn = true;
        } else {
          spacing.pageX = 0;
        }
        this.position = spacing;
      }
    },
    handlerButton(event) {
      if (this.closable) {
        this.closeButtonGroup();
      }
      const dataset = event.currentTarget.dataset;
      this.$emit("click", {
        index: Number(dataset.index),
        item: this.params
      });
    },
    closeButtonGroup() {
      this.position = {
        pageX: 0,
        pageY: 0
      };
      this.isShowBtn = false;
    },
    //控制自定义组件
    handlerParentButton(event) {
      if (this.closable) {
        this.closeButtonGroup();
      }
    },
    px(num) {
      return uni.upx2px(num) + "px";
    }
  }
};
</script>

<style>
.tui-swipeout-wrap {
  /* background: #fff; */
  background: transparent;
  position: relative;
  overflow: hidden;
}

.swipe-action-show {
  position: relative;
  z-index: 99999;
}

.tui-swipeout-item {
  width: 100%;
  /* padding: 15px 20px; */
  box-sizing: border-box;
  transition: transform 0.2s ease;
  font-size: 14px;
}

.tui-swipeout-content {
  white-space: nowrap;
  overflow: hidden;
}

.tui-swipeout-button-right-group {
  position: absolute;
  right: -100%;
  top: 0;
  height: 100%;
  z-index: 1;
  width: 100%;
}

.tui-swipeout-button-right-item {
  height: 100%;
  float: left;
  white-space: nowrap;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}

.swipe-action_mask {
  display: block;
  opacity: 0;
  position: fixed;
  z-index: 999;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
</style>
